package com.cxx.purchasecharge.component.controller.usersecurity;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cxx.purchasecharge.component.bean.ActionResult;
import com.cxx.purchasecharge.component.bean.ActionResult.ActionResultStatus;
import com.cxx.purchasecharge.component.bean.DataGridRequestForm;
import com.cxx.purchasecharge.component.bean.GenericPagingResult;
import com.cxx.purchasecharge.component.bean.usersecurity.RoleBean;
import com.cxx.purchasecharge.component.bean.usersecurity.UserBean;
import com.cxx.purchasecharge.component.controller.GenericController;
import com.cxx.purchasecharge.component.utils.AjaxUtils;
import com.cxx.purchasecharge.component.utils.BeanConvertUtils;
import com.cxx.purchasecharge.component.utils.ComponentConstants;
import com.cxx.purchasecharge.component.utils.MessageProperties;
import com.cxx.purchasecharge.core.model.persistence.User;
import com.cxx.purchasecharge.dal.UserDao;

@Controller
@RequestMapping ("/user")
public class UserManager extends GenericController<UserBean>
{
    private static final Logger logger = Logger.getLogger (UserManager.class);

    @Autowired
    private UserDao userDao;
    
    public UserManager () 
    {
        super.setViewName("userManagement");
    }

    @Override
    public String checkExist(@RequestParam String userUniqueId, @RequestParam String userId, HttpServletRequest request)
    {
        if (StringUtils.isBlank (userUniqueId))
        {
            // new
            User obj = userDao.findByUserId (userId);
            if (null != obj)
            {
                return "false";
            }
        }
        else
        {
            // edit
            long uid = Long.parseLong (userUniqueId);
            User user = userDao.findByUserId (userId);
            if (null != user && user.getId () != uid)
            {
                return "false";
            }
        }

        return "true";
    }

    @Override
    public String getAllModel(DataGridRequestForm dataGridRequestForm, HttpServletRequest request)
    {
        List <User> users = (List <User>) userDao.findAll ();

        JSONArray jsonArr = JSONArray.fromObject (BeanConvertUtils.userList2UserBeanList (users));
        return jsonArr.toString ();
    }

    @Override
    public String addModel(UserBean bean, BindingResult bindingResult, HttpServletRequest request)
    {
        preprocessUser (bean, request);
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                userDao.save (BeanConvertUtils.userBean2User (bean));
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_SUCCESS,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_FAIL,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @Override
    public String updateModel(UserBean bean, BindingResult bindingResult, HttpServletRequest request)
    {
        preprocessUser (bean, request);
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                User user = BeanConvertUtils.userBean2User (bean);
                user.setPwd (userDao.findOne (user.getId ()).getPwd ());
                userDao.save (user);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_SUCCESS,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_FAIL,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @Override
    public String deleteModels(@RequestParam String ids, HttpServletRequest request)
    {
        if (null != ids && ids.trim ().length () > 0)
        {
            User user;
            List <User> users = new ArrayList <User> ();
            if (ids.indexOf (";") != -1)
            {
                String[] idArr = ids.split (";");
                for (String id : idArr)
                {
                    user = new User ();
                    user.setId (Long.parseLong (id));
                    users.add (user);
                }
            }
            else
            {
                user = new User ();
                user.setId (Long.parseLong (ids));
                users.add (user);
            }

            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                userDao.delete (users);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_SUCCESS,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_FAIL,
                                                                                       ComponentConstants.MSG_USER))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            logger.error (ActionResultStatus.BAD_REQUEST);
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @RequestMapping (value = "/getUsers", method = RequestMethod.POST)
    public @ResponseBody
    String getUsers (DataGridRequestForm dataGridRequestForm)
    {
        int page = dataGridRequestForm.getPage () - 1;
        int size = dataGridRequestForm.getRows ();
        String sortField = parseSortField (dataGridRequestForm.getSort ());
        String order = dataGridRequestForm.getOrder ();
        Pageable pageable = new PageRequest (page, size, new Sort ("asc".equalsIgnoreCase (order) ? Direction.ASC
                                                                                                 : Direction.DESC,
                                                                   sortField));
        String searchKey = (null == dataGridRequestForm.getSearchKey () ? "" : dataGridRequestForm.getSearchKey ()
                                                                                                  .trim ());
        Page <User> userPage = userDao.findByFuzzy (pageable, searchKey);
        List <User> users = userPage.getContent ();
        long total = userPage.getTotalElements ();
        GenericPagingResult <UserBean> userPagingResult = new GenericPagingResult <UserBean> ();
        userPagingResult.setRows (BeanConvertUtils.userList2UserBeanList (users));
        userPagingResult.setTotal (total);

        JSONObject jsonObject = JSONObject.fromObject (userPagingResult);
        return jsonObject.toString ();
    }

    private String parseSortField (final String sortField)
    {
        String sortFieldAfterParse = "userId";
        if (!StringUtils.isBlank (sortField))
        {
            if (ComponentConstants.PHONE.equalsIgnoreCase (sortField))
            {
                sortFieldAfterParse = ComponentConstants.MOBILE_PHONE;
            }
        }
        return sortFieldAfterParse;
    }

    private void preprocessUser (UserBean userBean, HttpServletRequest request)
    {
        String roles = request.getParameter ("roles");
        if (StringUtils.isNotBlank (roles))
        {
            List <RoleBean> roleBeans = new ArrayList <RoleBean> ();
            RoleBean roleBean = null;
            String[] roleArr = roles.split (",");
            for (String roleId : roleArr)
            {
                roleBean = new RoleBean ();
                roleBean.setId (roleId);
                roleBeans.add (roleBean);
            }
            userBean.setRoleBeans (roleBeans);
        }
    }

}
